#include "dingdong.h"
#include <QFileDialog>
#include <QtGui/QMessageBox>
#include <QScrollArea>
#include <QColorDialog>


	static int imageID = 1;
DingDong::DingDong(QWidget *parent, Qt::WFlags flags)
	: QMainWindow(parent, flags)
{
	ui.setupUi(this);

	//Setting up Click Events for toolbar buttons
	this->toolSignalMapper = new QSignalMapper(this);
	connect(ui.PaintBrush, SIGNAL(clicked()), toolSignalMapper, SLOT(map()));
    connect(ui.EyedropperTool, SIGNAL(clicked()), toolSignalMapper, SLOT(map()));
    toolSignalMapper->setMapping(ui.PaintBrush, "PaintBrush");
    toolSignalMapper ->setMapping(ui.EyedropperTool, "EyedropperTool");

	connect(toolSignalMapper, SIGNAL(mapped(QString)), this, SLOT(toggleTool(QString)));

	currentTool = new QLabel(this);
	currentTool->blockSignals(true);
	currentTool->setMaximumSize(0,0);
	currentTool->setText("");
	currentTool->setObjectName("currentTool");

	this->setObjectName("MainWindow");
	imageTabs = new QTabWidget(this);
	setCentralWidget(imageTabs);
    connect(ui.actionOpen, SIGNAL(triggered()), this, SLOT(open()));
	connect(ui.actionExit, SIGNAL(triggered()), this, SLOT(exit()));
	connect(ui.actionClose, SIGNAL(triggered()), this, SLOT(close()));
	connect(ui.actionSave, SIGNAL(triggered()), this, SLOT(save()));
	connect(ui.actionSave_As, SIGNAL(triggered()), this, SLOT(saveAs()));
	connect(ui.actionColor, SIGNAL(triggered()), this, SLOT(colorPicker()));
	connect(ui.actionInvert, SIGNAL(triggered()), this, SLOT(negative()));
	connect(ui.actionDesaturate, SIGNAL(triggered()), this, SLOT(grayscale()));
	connect(ui.actionZoom_In, SIGNAL(triggered()), this, SLOT(zoomIn()));
    connect(ui.actionZoom_Out, SIGNAL(triggered()), this, SLOT(zoomOut()));
    connect(ui.action400, SIGNAL(triggered()), this, SLOT(pixelation()));
    connect(ui.actionAbout, SIGNAL(triggered()), this, SLOT(gaussian()));
    connect(ui.action200, SIGNAL(triggered()), this, SLOT(sepia()));        
    connect(ui.action100, SIGNAL(triggered()), this, SLOT(edgeDetect()));   
    connect(ui.action50, SIGNAL(triggered()), this, SLOT(emboss()));        
    connect(ui.action25, SIGNAL(triggered()), this, SLOT(sharpen()));
	//connect(ui.actionOpen_URL, SIGNAL(triggered()), this, SLOT(on_action_Download_triggered()));
		netManager = new QNetworkAccessManager(this);
    connect(netManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(slot_netwManagerFinished(QNetworkReply*)));

}

DingDong::~DingDong()
{

}
//When setting the text of the current tool, set it to be equal
//to the widget name given to the tool in ui_dingdong.h

void DingDong::toggleTool(const QString toolName)
{
		//Refactored by aDavis - 03/05/2012
		if(this ->currentTool->text() != "")
		{
			QToolButton* selectedTool = this->findChild<QToolButton*>(this ->currentTool->text());
			selectedTool ->setChecked(false);              
		}

		QToolButton* aselectedTool = this->findChild<QToolButton*>(toolName);
		aselectedTool->setChecked(true);
		this->currentTool->setText(toolName);
		
}

void DingDong::exit()
{
	qApp->quit();

}

void DingDong::close()
{
	imageTabs->currentWidget()->deleteLater();
	
	QLabel *imgLabel = imageTabs->currentWidget()->findChild<QLabel *>();
	delete imgLabel;
	imageTabs->removeTab(imageTabs->currentIndex());
}

void DingDong::save()
{

	QString fileLocation = imageTabs->tabText(imageTabs->currentIndex());
    PaintImage *currentImage = imageTabs->findChild<PaintImage*>(fileLocation);
	currentImage->saveImage(fileLocation, QFileInfo(fileLocation).completeSuffix().toStdString().c_str());
}

void DingDong::saveAs()
{
	QFileDialog *fileDailog = new QFileDialog(this);
	QString fileName =  fileDailog->getSaveFileName(this, tr("Save as....."), "",
    tr("JPG (*.jpg );;.PNG(*.png)"));
	
	QFile file(fileName);

	QFileInfo *fileInfo = new QFileInfo(file);

	PaintImage *currentImage = imageTabs->findChild<PaintImage*>();


	currentImage->saveImage(fileName, fileInfo->suffix().toStdString().c_str());
}
/*

*/
void DingDong::open()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "",
        tr("Image Files (*.jpg *.png)"));

    if (fileName != "") {
        QFile file(fileName);
        if (!file.open(QIODevice::ReadOnly)) {
            QMessageBox::critical(this, tr("Error"), tr("Could not open file"));
            return;
        }
		QFileInfo *fileInfo;

		try
		{
			fileInfo= new QFileInfo(file);
		}

		catch(...) 
		{
			/*TO-DO: Add Error Handling*/
			std::string errors = "Error loading file";
		}
		
		addNewImage(fileInfo->absoluteFilePath());

        file.close();
    }


}

void DingDong::addNewImage(QString& fileLocation)
{
	++imageID;
	QString newName = imageID;
	PaintImage *newImage = new PaintImage(this);
	newImage->setObjectName(fileLocation);
	newImage->openImage(fileLocation);

	imageTabs->addTab(newImage, fileLocation);
	imageTabs->setCurrentWidget(newImage);
}

void DingDong::zoomIn()
{
	scale(1.6);
		
}

void DingDong::zoomOut()
{
	scale(.625);	
}

void DingDong::scale(double factor)
{
	QLabel *imgLabel = imageTabs->currentWidget()->findChild<QLabel *>(); 
	const QPixmap *currentPixmap = imgLabel->pixmap();          
	QImage currentImage = currentPixmap->toImage(); 
	
	imgLabel -> resize(factor * imgLabel -> size());
}

void DingDong::negative()
{
	QString currentObjectName = imageTabs->currentWidget()->objectName();
	PaintImage *currentImage = imageTabs->findChild<PaintImage*>(currentObjectName);
	NegativeFilter *negFilter;
	negFilter = new NegativeFilter();
	currentImage->applyFilter(negFilter);
	imageTabs->repaint();
}

void DingDong::colorPicker()
{
	PaintImage *currentImage = imageTabs->findChild<PaintImage*>();
	QColorDialog *color = new QColorDialog;
	QColor selectedColor = QColorDialog::getColor(Qt::red, this, "Text Color",  QColorDialog::DontUseNativeDialog);
	currentImage->setPenColor(selectedColor);
}

void DingDong::eyeDropper()
{
        PaintImage *currentImage = imageTabs -> findChild<PaintImage*>();
        QRgb pick = currentImage -> getImage().pixel(currentImage ->getLastPoint());
        QColor color(pick);

        PaintImage::myPenColor = color;
}


void DingDong::grayscale()
{
        QString currentObjectName = imageTabs->currentWidget()->objectName();
        PaintImage *currentImage = imageTabs->findChild<PaintImage*>(currentObjectName);
        grayscaleFilter *grayFilter;
        grayFilter = new grayscaleFilter();
        currentImage->applyFilter(grayFilter);
        imageTabs->repaint();   
}

void DingDong::gaussian()
{
        QString currentObjectName = imageTabs->currentWidget()->objectName();
        PaintImage *currentImage = imageTabs->findChild<PaintImage*>(currentObjectName);
        gaussianFilter *gaussFilter;
        gaussFilter = new gaussianFilter();
        currentImage->applyFilter(gaussFilter);
        imageTabs->repaint();
}

void DingDong::sepia()
{
        QString currentObjectName = imageTabs->currentWidget()->objectName();
        PaintImage *currentImage = imageTabs->findChild<PaintImage*>(currentObjectName);
        sepiaFilter *sepFilter;
        sepFilter = new sepiaFilter();
        sepFilter ->setName("Sepia");
        currentImage ->applyFilter(sepFilter);
        imageTabs ->repaint();
}

void DingDong::edgeDetect()
{
        QString currentObjectName = imageTabs->currentWidget()->objectName();
        PaintImage *currentImage = imageTabs->findChild<PaintImage*>(currentObjectName);
        edgeDetectFilter *edgeFilter;
        edgeFilter = new edgeDetectFilter();
        //edgeFilter ->setName("Sepia");
        currentImage ->applyFilter(edgeFilter);
        imageTabs ->repaint();
}

void DingDong::emboss()
{
        QString currentObjectName = imageTabs->currentWidget()->objectName();
        PaintImage *currentImage = imageTabs->findChild<PaintImage*>(currentObjectName);
        embossFilter *emb;
        emb = new embossFilter();
        //edgeFilter ->setName("Sepia");
        currentImage ->applyFilter(emb);
        imageTabs ->repaint();
}

void DingDong::sharpen()
{
        QString currentObjectName = imageTabs->currentWidget()->objectName();
        PaintImage *currentImage = imageTabs->findChild<PaintImage*>(currentObjectName);
        sharpenFilter *sharp;
        sharp = new sharpenFilter();
        //edgeFilter ->setName("Sepia");
        currentImage ->applyFilter(sharp);
        imageTabs ->repaint();
}




/*Big ups to http://www.qtforum.org/article/33674/how-can-i-download-an-image-from-an-http-url.html
*/
void DingDong::on_action_Download_triggered()
{
	bool ok;
     QString text = QInputDialog::getText(this, tr("QInputDialog::getText()"),
                                          tr("URL"), QLineEdit::Normal,
                                          QDir::home().dirName(), &ok);
     if (ok && !text.isEmpty())
	 {
		QUrl url(text);
		QNetworkRequest request(url);
		netManager->get(request);
	 }
}

void DingDong::slot_netwManagerFinished(QNetworkReply *reply)
{
    if (reply->error() != QNetworkReply::NoError) {
        reply->deleteLater();
        return;
    }
    QVariant redir = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
    if (redir.isValid()) {
        QUrl url = redir.toUrl();
        if (url.isRelative()) {
            url.setScheme(reply->url().scheme());
            url.setEncodedHost(reply->url().encodedHost());
        }
        QNetworkRequest req(url);
       netManager->get(req);
        reply->deleteLater();
        return;
    }

    QByteArray jpegData = reply->readAll();

    QImage urlImage;
    urlImage.loadFromData(jpegData);
	QString newName = imageID;
	PaintImage *newImage = new PaintImage(this);
	newImage->setObjectName(newName);
	newImage->openImage(urlImage);

	imageTabs->addTab(newImage, "newImage" + newName);
	imageTabs->setCurrentWidget(newImage);

    reply->deleteLater();
}

void DingDong::pixelation()
{
        QString currentObjectName = imageTabs->currentWidget()->objectName();
        PaintImage *currentImage = imageTabs->findChild<PaintImage*>(currentObjectName);
        pixelationFilter *pixFilter;
        pixFilter = new pixelationFilter();
        pixFilter ->setName("Pixelation");
        currentImage->applyFilter(pixFilter);
        imageTabs->repaint();
}